package com.inkyi.assistant.app.notepad;

import com.formdev.flatlaf.FlatClientProperties;
import com.inkyi.assistant.app.base.BaseFrame;
import com.inkyi.assistant.app.notepad.entity.NoteListData;
import com.inkyi.assistant.app.notepad.event.NoteEvent;
import com.inkyi.assistant.app.notepad.event.NoteEventListener;
import com.inkyi.assistant.app.notepad.event.NoteWorkspaceListener;
import com.inkyi.framework.common.utils.EmptyHelper;
import com.inkyi.framework.daqian.share.component.SearchField;
import com.inkyi.framework.daqian.share.jtree.DefaultTransferHanlder;
import com.inkyi.framework.docdb.DocOption;
import com.inkyi.framework.docdb.DocRecord;
import org.jdesktop.swingx.JXTree;

import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Objects;

/**
 * 目录
 */
public class NoteListingsPanel extends JPanel {

    private final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();

    private final DefaultTreeModel treeModel = new DefaultTreeModel(rootNode);

    private final JXTree tree = new JXTree(treeModel);

    private final JScrollPane scrollPane = new JScrollPane(tree);

    private final JPanel headerPanel = new JPanel();
    /**
     * 右键菜单
     */
    private final JPopupMenu popupMenu = new JPopupMenu();
    /**
     * 菜单-新建
     */
    private final JMenuItem jmiNew = new JMenuItem("新建文档");
    /**
     * 菜单-重命名
     */
    private final JMenuItem jmiRename = new JMenuItem("重命名");
    /**
     * 菜单-打开
     */
    private final JMenuItem jmiOpen = new JMenuItem("打开");
    /**
     * 菜单-删除
     */
    private final JMenuItem jmiDelete = new JMenuItem("删除");
    /**
     * 新建笔记本
     */
    private final JMenuItem jmiNewNotepad = new JMenuItem("新建笔记本");

    private final SearchField searchField = new SearchField();

    public NoteListingsPanel() {
        setupUI();
        initConfig();
    }

    public JPanel getHeaderPanel() {
        return headerPanel;
    }


    public void setupUI() {
        this.setLayout(new BorderLayout());

        headerPanel.setLayout(new BorderLayout());
        headerPanel.add(searchField, BorderLayout.CENTER);

        add(headerPanel, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);
    }


    public void initConfig() {

        // 触发节点的展开或折叠操作
        tree.setToggleClickCount(0);
        // 显示根节点的扩展按钮
        tree.setShowsRootHandles(true);
        //圆形的选择
        tree.expandRow(1);
        // 显示根节点
        tree.setRootVisible(true);
        // 拖拽
        tree.setDragEnabled(true);
        tree.setDropMode(DropMode.ON_OR_INSERT);
        tree.setTransferHandler(new DefaultTransferHanlder());
        tree.putClientProperty(FlatClientProperties.STYLE, "selectionInsets: 0,1,0,1; selectionArc: 6");
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
        tree.addMouseListener(new MouseAdapter() {
            /**
             * 右键弹出菜单
             * @param e the event to be processed
             */
            public void mousePressed(MouseEvent e) {
                // 双击打开 - 面板要检测是否已经打开了，如果打开了，就切换。
                if (MouseEvent.BUTTON1 == e.getButton()) {
                    if (e.getClickCount() == 2) {
                        NoteListData userObject = getSelectedUserObject();
                        if (userObject != null) {
                            doActionPerformed(NoteEvent.of(e.getSource(), NoteEvent.TYPE_OPEN_NODE, userObject));
                        }
                    }
                } else if (MouseEvent.BUTTON3 == e.getButton()) {
                    TreePath path = tree.getPathForLocation(e.getX(), e.getY());
                    if (path != null) {
                        tree.setSelectionPath(path);
                    }
                    DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) tree.getModel().getRoot();
                    DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                    popupMenu.removeAll();
                    if (Objects.equals(selectedNode, rootNode)) {
                        popupMenu.add(jmiNewNotepad);
                    } else {
                        popupMenu.add(jmiNew);
                        popupMenu.add(jmiRename);
                        popupMenu.add(jmiOpen);
                        popupMenu.add(jmiDelete);
                    }
                    popupMenu.show(tree, e.getX(), e.getY());
                }
            }
        });
        rootNode.setUserObject(NoteListData.of("-1", "全部笔记"));
        // 新建
        jmiNew.addActionListener(e -> {
            NoteListData parentData = getSelectedUserObject();
            String parentId = parentData.getId();

            DocOption docOption = new DocOption();
            docOption.setParentId(parentId);
            DocRecord docRecord = NoteContext.createDocument();
            DocRecord nodeDataRecord = NoteContext.DATA_SOURCE.save(docRecord, docOption);

            NoteListData noteListData = NoteListData.of(nodeDataRecord.getId(), nodeDataRecord.getProperties().getTitle());
            addNodeData(noteListData);
            NoteEvent event = new NoteEvent(e.getSource(), NoteEvent.TYPE_NEW_NODE, noteListData);
            doActionPerformed(event);
        });
        // 重命名
        jmiRename.addActionListener(e -> {
            //获取选中结点的路径
            TreePath selectionPath = tree.getSelectionPath();
            if (selectionPath != null) {//如果选中结点不为空
                // 找到节点数据
                DefaultMutableTreeNode pathComponent = (DefaultMutableTreeNode) selectionPath.getLastPathComponent();
                if (pathComponent == null) {
                    return;
                }
                NoteListData userObject = (NoteListData) pathComponent.getUserObject();
                if (userObject == null) {
                    return;
                }
                Object newTitle = JOptionPane.showInputDialog(this, null, "重命名", JOptionPane.PLAIN_MESSAGE, null, null, userObject.getTitle());
                if (newTitle == null || newTitle.toString().isEmpty()) {
                    return;
                }
                userObject.setTitle(newTitle.toString());
                tree.updateUI();
                DocRecord nodeDataRecord = NoteContext.DATA_SOURCE.findById(userObject.getId());
                if (nodeDataRecord != null) {
                    nodeDataRecord.getProperties().setTitle(newTitle.toString());
                    NoteContext.DATA_SOURCE.update(nodeDataRecord);
                }
                NoteEvent event = new NoteEvent(e.getSource(), NoteEvent.TYPE_UPDATE_TITLE, userObject);
                doActionPerformed(event);
            }
        });
        // 删除
        jmiDelete.addActionListener(e -> {
            int isConfirm = JOptionPane.showConfirmDialog(this.getParent(), "是否要删除这个笔记");
            if (isConfirm == JOptionPane.OK_OPTION) {
                NoteListData userObject = getSelectedUserObject();
                delNodeData(userObject);
                NoteContext.DATA_SOURCE.delete(userObject.getId());
                NoteEvent event = new NoteEvent(e.getSource(), NoteEvent.TYPE_DEL_NODE, userObject);
                doActionPerformed(event);
            }
        });
        // 打开
        jmiOpen.addActionListener(e -> {
            NoteListData userObject = getSelectedUserObject();
            NoteEvent event = new NoteEvent(e.getSource(), NoteEvent.TYPE_OPEN_NODE, userObject);
            doActionPerformed(event);
        });
        // 新建笔记本
        jmiNewNotepad.addActionListener(e -> {
            String title = JOptionPane.showInputDialog("请输入笔记本名称");
            DocRecord docRecord = NoteContext.createNotepad(title);
            NoteContext.DATA_SOURCE.save(docRecord, new DocOption());
            NoteListData listData = NoteListData.of(docRecord.getId(), title);
            createNotebook(listData);
        });
        // 搜索框
        searchField.addActionListener(e -> {
            SearchField field = (SearchField) e.getSource();
            findInTree(field.getText());
        });
        // 添加监听
        this.addListener(new NoteWorkspaceListener());
        // 处理数据
        initData();
    }

    private void initData() {
        // 处理数据
        List<DocRecord> docRecords = NoteContext.findDataAll();
        if (!docRecords.isEmpty()) {
            initDataItem(rootNode, docRecords);
        }
    }

    private void initDataItem(DefaultMutableTreeNode currNode, List<DocRecord> records) {
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        for (int i = 0; i < records.size(); i++) {
            DocRecord record = records.get(i);
            if (!Objects.equals(NodeDataType.NODE_DOCUMENT.getKey(), record.getType()) && !Objects.equals(NodeDataType.NODE_NOTEPAD.getKey(), record.getType())) {
                continue;
            }
            NoteListData recordData = NoteListData.of(record.getId(), record.getProperties().getTitle());
            DefaultMutableTreeNode recordNode = new DefaultMutableTreeNode(recordData);
            // 放入当前节点
            model.insertNodeInto(recordNode, currNode, i);
            // 处理叶子数据
            List<DocRecord> children = record.getChildren();
            if (EmptyHelper.isEmpty(children)) {
                continue;
            }
            initDataItem(recordNode, children);
        }

    }

    /**
     * 获取选定用户对象
     *
     * @return {@link Object }
     */
    public NoteListData getSelectedUserObject() {
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        if (selectedNode != null && selectedNode.getParent() != null && selectedNode.getUserObject() instanceof NoteListData) {
            return (NoteListData) selectedNode.getUserObject();
        }
        return null;
    }

    /**
     * 获取选定用户对象
     *
     * @return {@link Object }
     */
    public NoteListData getNodeUserObject(DefaultMutableTreeNode node) {
        if (node != null && node.getParent() != null && node.getUserObject() instanceof NoteListData) {
            return (NoteListData) node.getUserObject();
        }
        return null;
    }


    /**
     * 添加记事本
     */
    public void createNotebook(NoteListData userObject) {
        // 树状模型
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        if (model == null) {
            return;
        }
        DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode) model.getRoot();
        //创建新结点
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(userObject);
        //使用TreeModel的方法添加，不需要手动刷新UI
        model.insertNodeInto(newNode, rootNode, 0);
        //显示新结点
        TreeNode[] pathToRoot = model.getPathToRoot(newNode);
        TreePath treePath = new TreePath(pathToRoot);
        tree.scrollPathToVisible(treePath);

    }

    /**
     * 添加记事本
     */
    public void addNodeData(NoteListData userObject) {
        // 树状模型
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
        if (model == null) {
            return;
        }
        //获取选中结点
        DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
        if (selectedNode == null) {
            return;
        }
        //创建新结点
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(userObject);
        //使用TreeModel的方法添加，不需要手动刷新UI
        model.insertNodeInto(newNode, selectedNode, 0);
        //显示新结点
        TreeNode[] pathToRoot = model.getPathToRoot(newNode);
        TreePath treePath = new TreePath(pathToRoot);
        tree.scrollPathToVisible(treePath);
    }

    /**
     * 删除笔记记录
     */
    public void delNodeData(NoteListData record) {
        Enumeration<TreeNode> nodes = rootNode.breadthFirstEnumeration();
        while (nodes.hasMoreElements()) {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) nodes.nextElement();
            NoteListData userObject = getNodeUserObject(node);
            if (userObject == null) {
                continue;
            }
            if (!Objects.equals(userObject.getId(), record.getId())) {
                continue;
            }
            int childCount = node.getChildCount();
            if (childCount == 0) {
                treeModel.removeNodeFromParent(node);
                break;
            }
            if (childCount > 0) {
                int dialogOption = JOptionPane.showConfirmDialog(this.getParent(), "文件夹不为空，是否全部删除");
                if (dialogOption != JOptionPane.OK_OPTION) {
                    break;
                }
                delAllNodes(node);
                break;
            }
        }
    }

    /**
     * 删除所有节点 - 遍历删除
     *
     * @param node 节点
     */
    private void delAllNodes(DefaultMutableTreeNode node) {
        if (node == null) {
            return;
        }
        int childCount = node.getChildCount();
        if (childCount > 0) {
            ArrayList<TreeNode> treeNodeList = new ArrayList<>();
            for (int i = 0; i < childCount; i++) {
                TreeNode childAt = node.getChildAt(i);
                if (childAt == null) {
                    continue;
                }
                treeNodeList.add(childAt);
            }
            for (TreeNode treeNode : treeNodeList) {
                if (treeNode instanceof DefaultMutableTreeNode) {
                    delAllNodes((DefaultMutableTreeNode) treeNode);
                }
            }
        }
        NoteListData userObject = getNodeUserObject(node);
        treeModel.removeNodeFromParent(node);
        NoteEvent event = new NoteEvent(this, NoteEvent.TYPE_DEL_NODE, userObject);
        doActionPerformed(event);
    }

    public void addListener(NoteEventListener listener) {
        listenerList.add(NoteEventListener.class, listener);
    }

    public void delListener(NoteEventListener listener) {
        listenerList.remove(NoteEventListener.class, listener);
    }

    private void doActionPerformed(NoteEvent event) {
        NoteEventListener[] listeners = listenerList.getListeners(NoteEventListener.class);
        for (NoteEventListener listener : listeners) {
            listener.actionPerformed(event);
        }
    }

    /**
     * 在树上查找
     *
     * @param str str
     */
    private void findInTree(String str) {

    }


    public static void main(String[] args) {
        BaseFrame baseFrame = new BaseFrame();

        JSplitPane mainPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);

        NoteListingsPanel noteCatalogPanel = new NoteListingsPanel();

        noteCatalogPanel.setPreferredSize(new Dimension(250, 0));
        mainPane.setLeftComponent(noteCatalogPanel);
        mainPane.setRightComponent(new JLabel());

        baseFrame.add(mainPane);
        baseFrame.setVisible(true);

    }


}
